package com.ruoyi.common.filter;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.StringJsonUtils;
import com.ruoyi.common.utils.ToolUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @Description: 参数去除左右空格
 * @Author: LJ
 * @Date: 2018-06-12 17:33
 * @version:
 */
@Slf4j
public class ParameterRequestWrapper extends HttpServletRequestWrapper {

    private Map<String, String[]> params = new HashMap<String, String[]>();


    public ParameterRequestWrapper(HttpServletRequest request) {
        // 将request交给父类，以便于调用对应方法的时候，将其输出，其实父亲类的实现方式和第一种new的方式类似
        super(request);
        //将参数表，赋予给当前的Map以便于持有request中的参数
        this.params.putAll(request.getParameterMap());
        this.modifyParameterValues();//将parameter的值去除空格后重写回去并且空处理
    }

    /**
     * 重写getInputStream方法  post类型的请求参数必须通过流才能获取到值
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        /** 非json类型，直接返回 */
        try {
            if (!super.getHeader(HttpHeaders.CONTENT_TYPE).toLowerCase().contains(MediaType.APPLICATION_JSON_VALUE)) {
                return super.getInputStream();
            }
        }catch (Exception e){
            return super.getInputStream();
        }
        //为空，直接返回
        String json = IOUtils.toString(super.getInputStream(), "UTF-8");
        if (ToolUtil.isEmpty(json)) {
            return super.getInputStream();
        }
        log.debug("去除POST请求数据两端的空格前参数= {}", json);
        Object jsonObj = JSON.parse(json);
        if (jsonObj instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) jsonObj;
            StringJsonUtils.parseJsonObject(jsonObject);
        } else if (jsonObj instanceof JSONArray) {
            JSONArray jsonArray = (JSONArray) jsonObj;
            StringJsonUtils.parseJSONArray(jsonArray);
        }
        log.debug("去除POST请求数据两端的空格后参数= {}", JSON.toJSONString(jsonObj));
        ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(jsonObj).getBytes("UTF-8"));
        return new MyServletInputStream(bis);
    }

    public void modifyParameterValues() {//将parameter的值去除空格后重写回去
        Set<String> set = params.keySet();
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            String[] values = params.get(key);
            values[0] = values[0].trim();
            if ("".equals(values[0]) || "null".equalsIgnoreCase(values[0]) || "undefined".equalsIgnoreCase(values[0])) {
                values[0] = null;
            }
            params.put(key, values);
        }
    }

    @Override
    public String getParameter(String name) {//重写getParameter，代表参数从当前类中的map获取
        String[] values = params.get(name);
        if (values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    public String[] getParameterValues(String name) {//同上
        return params.get(name);
    }

    class MyServletInputStream extends ServletInputStream {
        private ByteArrayInputStream bis;

        public MyServletInputStream(ByteArrayInputStream bis) {
            this.bis = bis;
        }

        @Override
        public boolean isFinished() {
            return true;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(ReadListener listener) {

        }

        @Override
        public int read() {
            return bis.read();
        }
    }

    //    //重载一个构造方法
//    public ParameterRequestWrapper(HttpServletRequest request, Map<String, Object> extendParams) {
//        this(request);
//        addAllParameters(extendParams);//这里将扩展参数写入参数表
//    }
    //    public void addAllParameters(Map<String, Object> otherParams) {//增加多个参数
//        for (Map.Entry<String, Object> entry : otherParams.entrySet()) {
//            addParameter(entry.getKey(), entry.getValue());
//        }
//    }
//
//    public void addParameter(String name, Object value) {//增加参数
//        if (value != null) {
//            if (value instanceof String[]) {
//                params.put(name, (String[]) value);
//            } else if (value instanceof String) {
//                params.put(name, new String[]{(String) value});
//            } else {
//                params.put(name, new String[]{String.valueOf(value)});
//            }
//        }
//    }
}
